/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.bef.bemanager.service;

import com.inspur.edp.bef.bemanager.util.CheckInfoUtil;
import com.inspur.edp.bef.bizentity.GspBizEntityElement;
import com.inspur.edp.bef.bizentity.GspBizEntityObject;
import com.inspur.edp.bef.bizentity.GspBusinessEntity;
import com.inspur.edp.bef.bizentity.common.InternalActionUtil;
import com.inspur.edp.bef.bizentity.operation.BizOperation;
import com.inspur.edp.cef.designtime.api.IGspCommonField;
import com.inspur.edp.cef.designtime.api.element.GspAssociation;
import com.inspur.edp.cef.designtime.api.util.MetadataUtil;
import com.inspur.edp.das.commonmodel.IGspCommonObject;
import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import com.inspur.edp.lcm.metadata.api.entity.MetadataReference;
import com.inspur.edp.metadata.rtcustomization.api.CustomizationService;
import com.inspur.edp.metadata.rtcustomization.spi.IMetadataRtReferenceManager;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;
import java.util.ArrayList;
import java.util.List;

public class MetadataRtReferenceService implements IMetadataRtReferenceManager {

  private void buildMetadataReference(GspMetadata metadata) {
    if (metadata == null) {
      metadata.setRefs(new ArrayList());
    }
    CustomizationService CustomizationService = (CustomizationService) SpringBeanUtils
        .getBean(CustomizationService.class);
    GspBusinessEntity bizEntity = (GspBusinessEntity) metadata.getContent();

    if (CheckInfoUtil.checkNull(bizEntity.getDependentEntityId())) {
      buildReference(bizEntity.getDependentEntityId(), metadata, CustomizationService);
    }

    if (bizEntity.getBizMgrActions() != null && bizEntity.getBizMgrActions().getCount() > 0) {

      for (BizOperation mgrAction : bizEntity.getBizMgrActions()) {

        if (!InternalActionUtil.InternalMgrActionIDs.contains(mgrAction.getID())) {
          buildCompReference(mgrAction, metadata, CustomizationService);
        }
      }
    }
    dealObjectReference(bizEntity.getMainObject(), metadata, CustomizationService);
  }


  public void buildCompReference(BizOperation operation, GspMetadata metadata,
      CustomizationService CustomizationService) {
    buildReference(operation.getComponentId(), metadata, CustomizationService);
  }


  private void buildReference(String refMetadataId, GspMetadata metadata,
      CustomizationService CustomizationService) {
    if (CheckInfoUtil.checkNull(refMetadataId)) {
      return;
    }

    for (MetadataReference metadataReference : metadata.getRefs()) {
      if (refMetadataId.equals(metadataReference.getDependentMetadata().getId())) {
        return;
      }
    }
    GspMetadata refMetaData = MetadataUtil.getCustomMetadata(refMetadataId);
    if (refMetaData == null) {
      throw new RuntimeException(
          "根据metadata.rtcustomization.api.CustomizationService 未找到关联的元数据，元数据ID为：【" + refMetadataId
              + "】,请确认");
    }
    MetadataReference metadataReference = new MetadataReference();
    metadataReference.setMetadata(metadata.getHeader());
    metadataReference.setDependentMetadata(refMetaData.getHeader());
    metadata.getRefs().add(metadataReference);
  }


  private void dealObjectReference(GspBizEntityObject obj, GspMetadata metadata,
      CustomizationService CustomizationService) {
    if (obj.getContainElements() != null && obj.getContainElements().getCount() > 0) {
      for (IGspCommonField ele : obj.getContainElements()) {
        dealElementReference((GspBizEntityElement) ele, metadata, CustomizationService);
      }
    }
    if (obj.getBizActions() != null && obj.getBizActions().getCount() > 0) {

      for (BizOperation action : obj.getBizActions()) {

        if (!InternalActionUtil.InternalBeActionIDs.contains(action.getID())) {
          buildCompReference(action, metadata, CustomizationService);
        }
      }
    }

    if (obj.getDeterminations() != null && obj.getDeterminations().getCount() > 0) {
      for (BizOperation determination : obj.getDeterminations()) {
        buildCompReference(determination, metadata, CustomizationService);
      }
    }
    if (obj.getValidations() != null && obj.getValidations().getCount() > 0) {
      for (BizOperation validation : obj.getValidations()) {
        buildCompReference(validation, metadata, CustomizationService);
      }
    }
    if (obj.getContainChildObjects() != null && obj.getContainChildObjects().getCount() > 0) {
      for (IGspCommonObject childObj : obj.getContainChildObjects()) {
        dealObjectReference((GspBizEntityObject) childObj, metadata, CustomizationService);
      }
    }
  }


  private void dealElementReference(GspBizEntityElement element, GspMetadata metadata,
      CustomizationService CustomizationService) {
    if (element.getIsRef()) {
      return;
    }
    if (element.getIsUdt()) {

      buildReference(element.getUdtID(), metadata, CustomizationService);
    } else if (element.getHasAssociation()) {

      for (GspAssociation association : element.getChildAssociations()) {
        buildAssociationReference(association, metadata, CustomizationService);
      }
    }
  }


  private void buildAssociationReference(GspAssociation association, GspMetadata metadata,
      CustomizationService CustomizationService) {
    buildReference(association.getRefModelID(), metadata, CustomizationService);
  }


  public List<MetadataReference> getConstraint(GspMetadata gspMetadata) {
    if (gspMetadata.getRefs() != null) {
      //兼容inSuite场景
      if (!gspMetadata.getHeader().getId().startsWith("ins_")) {
        gspMetadata.getRefs().clear();
      }
    }
    buildMetadataReference(gspMetadata);
    List<MetadataReference> list = new ArrayList<MetadataReference>();
    if (gspMetadata.getRefs() != null && gspMetadata.getRefs().size() > 0) {
      for (MetadataReference item : gspMetadata.getRefs()) {
        list.add(item);
      }
    }
    return list;
  }
}
